package dcobluej.draw.view;

import Model.Core.IEntity;
import Model.Core.Impl.ObjectEntity;
import Model.Diagrams.StateMachine;
import Model.Draw.Coordinate;
import Model.Draw.Entities.LinkDraw;
import Model.Draw.Entities.StateDraw;
import Model.Draw.Entities.TransitionDraw;
import Model.Draw.IDraw;
import Model.Draw.IEntityDraw;
import Model.Draw.IMachineStateDraw;
import Model.Draw.IStateDraw;
import Model.Draw.Point;
import Presenter.CommunicationDiagramPresenter;
import Presenter.StateMachinePresenter;
import ViewInterfaces.ICommunicationDiagramDrawView;
import ViewInterfaces.IStateMachineDrawView;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Projeto TCC: Editor de diagramas de comunicação
 * @author jose.luz
 */
public class DrawDiagramView extends javax.swing.JFrame implements ICommunicationDiagramDrawView, IStateMachineDrawView {

    private static Color LightRed = new Color(255, 198, 184);
    private static Color Red = new Color(204, 0, 0);
    private static Color LightGreen = new Color(223, 255, 209);
    private static Color Green = new Color(0, 102, 51);
    private static Color Gray = new Color(240, 240, 240);
    private CommunicationDiagramPresenter communicationDiagramPresenter;
    private StateMachinePresenter stateMachinePresenter;
    private IEntity currentEntity;
    private List<IDraw> drawsToUpdate;
    private List<IEntityDraw> entityDraws;
    private List<IMachineStateDraw> stateDraws;
    private IDraw drawSelected;
    private IDraw drawToRename;
    private boolean isMoving;
    private JPanel currentPanel;
    private ActionListener communicationRenameAction = new ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            RenameCommunicationButtonActionPerformed(evt);
        }
    };
    private ActionListener stateRenameAction = new ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            RenameStateButtonActionPerformed(evt);
        }
    };
    private ActionListener communicationMoveAction = new ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            MoveCommunicationButtonActionPerformed(evt);
        }
    };
    private ActionListener stateMoveAction = new ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
            MoveStateButtonActionPerformed(evt);
        }
    };
    private ActionListener communicationConfirmRename = new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            communicationConfirmRenameButtonActionPerformed(evt);
        }
    };
    private ActionListener stateConfirmRename = new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            stateconfirmRenameButtonActionPerformed(evt);
        }
    };

    /** Creates new form DrawDiagramMaster */
    public DrawDiagramView() {
        initComponents();
        setButtonsListener();
        setTabListener();
        setActionButtonsActions();
        communicationDiagramPresenter = new CommunicationDiagramPresenter(this);
        stateMachinePresenter = new StateMachinePresenter(this);
        entityDraws = new ArrayList<IEntityDraw>();
        stateDraws = new ArrayList<IMachineStateDraw>();
        drawsToUpdate = new ArrayList<IDraw>();
        currentPanel = DrawAreaPanel;
        enableDcoContext(true);
    }

    private void setActionButtonsActions() {
        RenameButton.addActionListener(communicationRenameAction);
        MoveButton.addActionListener(communicationMoveAction);
    }

    private void setTabListener() {
        ChangeListener tabChangeListener = new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                JTabbedPane tabPane = (JTabbedPane) e.getSource();
                currentPanel = (JPanel) tabPane.getComponentAt(tabPane.getSelectedIndex());
                if (tabPane.getSelectedIndex() == 0) {
                    communicationDiagramPresenter.updateCanvas();
                    communicationDiagramPresenter.configureContext();
                } else {
                    stateMachinePresenter.updateCanvas();
                    stateMachinePresenter.setCurrentStateMachine(findStateMachineOf(currentPanel));
                    stateMachinePresenter.configureContext();
                }
                if (currentPanel.getMouseListeners().length == 0) {
                    currentPanel.addMouseListener(new java.awt.event.MouseAdapter() {

                        @Override
                        public void mousePressed(java.awt.event.MouseEvent e) {
                            if (isMoving) {
                                stateMachinePresenter.moveDraw((IMachineStateDraw) drawSelected, new Point(new Coordinate(e.getX()), new Coordinate(e.getY())));
                            } else {
                                stateMachinePresenter.newEntry(new Point(new Coordinate(e.getX()), new Coordinate(e.getY())));
                            }
                        }
                    });
                }
            }
        };
        DiagramTabbedPane.addChangeListener(tabChangeListener);
    }

    private void setButtonsListener() {
        dcoMenuControl.ObjectButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                communicationDiagramPresenter.unselectAll();
                communicationDiagramPresenter.objectEntitySelected();
                isMoving = false;
            }
        });

        dcoMenuControl.LinkButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                communicationDiagramPresenter.unselectAll();
                communicationDiagramPresenter.linkEntitySelected();
                isMoving = false;
            }
        });

        dcoMenuControl.MessageButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                communicationDiagramPresenter.unselectAll();
                communicationDiagramPresenter.messageEntitySelected();
                isMoving = false;
            }
        });

        dcoMenuControl.ActorButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                communicationDiagramPresenter.unselectAll();
                communicationDiagramPresenter.actorEntitySelected();
                isMoving = false;
            }
        });

        dmeMenuControl.StateButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                //TODO: PRESENTER SELECT THE STATE MODE
                stateMachinePresenter.unselectAll();
                stateMachinePresenter.stateSelected();
                isMoving = false;
            }
        });

        dmeMenuControl.TransitionButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                //TODO: PRESENTER SELECT THE TRANSITION MODE
                stateMachinePresenter.transitionSelected();
                isMoving = false;
            }
        });
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        DiagramDesktopPane = new javax.swing.JDesktopPane();
        renamePanel = new javax.swing.JPanel();
        renameTextField = new javax.swing.JTextField();
        RenameLabel = new javax.swing.JLabel();
        confirmRenameButton = new javax.swing.JButton();
        ActionToolBar = new javax.swing.JToolBar();
        RenameButton = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        MoveButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        messagePanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        MessageTextPane = new javax.swing.JTextPane();
        jLayeredPane1 = new javax.swing.JLayeredPane();
        alertIcon = new javax.swing.JLabel();
        hintIcon = new javax.swing.JLabel();
        DiagramTabbedPane = new javax.swing.JTabbedPane();
        DrawAreaPanel = new javax.swing.JPanel();
        dmeMenuControl = new dcobluej.draw.view.DmeMenuControl();
        dcoMenuControl = new dcobluej.draw.view.DrawMenuControl();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Construtor de Diagramas de comunicação");

        DiagramDesktopPane.setBackground(new java.awt.Color(204, 204, 204));

        renamePanel.setPreferredSize(new java.awt.Dimension(158, 100));

        renameTextField.setFont(new java.awt.Font("Tahoma", 0, 14));
        renameTextField.setToolTipText("Digite o nome do item selecionado");

        RenameLabel.setFont(new java.awt.Font("Tahoma", 0, 14));
        RenameLabel.setText("Renomear");

        confirmRenameButton.setFont(new java.awt.Font("Tahoma", 0, 14));
        confirmRenameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/check.png"))); // NOI18N
        confirmRenameButton.setText("Ok");
        confirmRenameButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                confirmRenameButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout renamePanelLayout = new javax.swing.GroupLayout(renamePanel);
        renamePanel.setLayout(renamePanelLayout);
        renamePanelLayout.setHorizontalGroup(
            renamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, renamePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(renamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(RenameLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(renameTextField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 138, Short.MAX_VALUE)
                    .addComponent(confirmRenameButton, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        renamePanelLayout.setVerticalGroup(
            renamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(renamePanelLayout.createSequentialGroup()
                .addGap(13, 13, 13)
                .addComponent(RenameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(renameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(confirmRenameButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        renamePanel.setBounds(0, 400, 158, 100);
        DiagramDesktopPane.add(renamePanel, javax.swing.JLayeredPane.PALETTE_LAYER);

        ActionToolBar.setFloatable(false);
        ActionToolBar.setRollover(true);

        RenameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Rename.png"))); // NOI18N
        RenameButton.setToolTipText("Renomear entidade");
        RenameButton.setBorderPainted(false);
        RenameButton.setEnabled(false);
        RenameButton.setFocusable(false);
        RenameButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        RenameButton.setMargin(new java.awt.Insets(2, 18, 2, 18));
        RenameButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ActionToolBar.add(RenameButton);
        ActionToolBar.add(jSeparator2);

        MoveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/move.png"))); // NOI18N
        MoveButton.setBorderPainted(false);
        MoveButton.setEnabled(false);
        MoveButton.setFocusable(false);
        MoveButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        MoveButton.setMargin(new java.awt.Insets(2, 18, 2, 18));
        MoveButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ActionToolBar.add(MoveButton);
        ActionToolBar.add(jSeparator1);

        ActionToolBar.setBounds(160, 0, 920, 40);
        DiagramDesktopPane.add(ActionToolBar, javax.swing.JLayeredPane.DEFAULT_LAYER);

        messagePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Painel de mensagem"));

        MessageTextPane.setBackground(new java.awt.Color(240, 240, 240));
        MessageTextPane.setBorder(null);
        MessageTextPane.setEditable(false);
        MessageTextPane.setFont(new java.awt.Font("Lucida Calligraphy", 0, 18));
        MessageTextPane.setForeground(new java.awt.Color(204, 0, 0));
        MessageTextPane.setRequestFocusEnabled(false);
        jScrollPane1.setViewportView(MessageTextPane);

        alertIcon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/alert.png"))); // NOI18N
        alertIcon.setVisible(false);
        alertIcon.setBounds(10, 0, 48, 50);
        jLayeredPane1.add(alertIcon, javax.swing.JLayeredPane.DEFAULT_LAYER);

        hintIcon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/hint.png"))); // NOI18N
        hintIcon.setVisible(false);
        hintIcon.setBounds(10, 0, 48, 50);
        jLayeredPane1.add(hintIcon, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout messagePanelLayout = new javax.swing.GroupLayout(messagePanel);
        messagePanel.setLayout(messagePanelLayout);
        messagePanelLayout.setHorizontalGroup(
            messagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(messagePanelLayout.createSequentialGroup()
                .addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 849, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        messagePanelLayout.setVerticalGroup(
            messagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(messagePanelLayout.createSequentialGroup()
                .addGroup(messagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 60, Short.MAX_VALUE)
                    .addComponent(jLayeredPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        messagePanel.setBounds(160, 40, 920, 90);
        DiagramDesktopPane.add(messagePanel, javax.swing.JLayeredPane.DEFAULT_LAYER);

        DiagramTabbedPane.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
        DiagramTabbedPane.setTabPlacement(javax.swing.JTabbedPane.RIGHT);

        DrawAreaPanel.setBackground(new java.awt.Color(255, 255, 255));
        DrawAreaPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                DrawAreaPanelMousePressed(evt);
            }
        });

        javax.swing.GroupLayout DrawAreaPanelLayout = new javax.swing.GroupLayout(DrawAreaPanel);
        DrawAreaPanel.setLayout(DrawAreaPanelLayout);
        DrawAreaPanelLayout.setHorizontalGroup(
            DrawAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 727, Short.MAX_VALUE)
        );
        DrawAreaPanelLayout.setVerticalGroup(
            DrawAreaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 425, Short.MAX_VALUE)
        );

        DiagramTabbedPane.addTab("<html><body topmargin=5 marginwidth=5 marginheight=15><font size=\"4\">Diagrama de comunicação</font></body></html>", DrawAreaPanel);

        DiagramTabbedPane.setBounds(160, 130, 920, 430);
        DiagramDesktopPane.add(DiagramTabbedPane, javax.swing.JLayeredPane.DEFAULT_LAYER);

        dmeMenuControl.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        dmeMenuControl.setVisible(true);
        dmeMenuControl.setBounds(0, 250, 160, 150);
        DiagramDesktopPane.add(dmeMenuControl, javax.swing.JLayeredPane.PALETTE_LAYER);

        dcoMenuControl.setVisible(true);
        dcoMenuControl.setBounds(0, 0, 160, 248);
        DiagramDesktopPane.add(dcoMenuControl, javax.swing.JLayeredPane.PALETTE_LAYER);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(DiagramDesktopPane, javax.swing.GroupLayout.PREFERRED_SIZE, 1081, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(DiagramDesktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 583, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void confirmRenameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_confirmRenameButtonActionPerformed
}//GEN-LAST:event_confirmRenameButtonActionPerformed

    private void DrawAreaPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_DrawAreaPanelMousePressed
        if (evt.getClickCount() == 2) {
            //TODO: show object machine state
        } else {
            Point clickedPoint = new Point(new Coordinate(evt.getX()), new Coordinate(evt.getY()));
            if (isMoving) {
                communicationDiagramPresenter.moveDraw(drawSelected, clickedPoint);
            } else {
                communicationDiagramPresenter.newEntry(clickedPoint);
            }
        }
    }//GEN-LAST:event_DrawAreaPanelMousePressed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToolBar ActionToolBar;
    private javax.swing.JDesktopPane DiagramDesktopPane;
    private javax.swing.JTabbedPane DiagramTabbedPane;
    private javax.swing.JPanel DrawAreaPanel;
    private javax.swing.JTextPane MessageTextPane;
    private javax.swing.JButton MoveButton;
    private javax.swing.JButton RenameButton;
    private javax.swing.JLabel RenameLabel;
    private javax.swing.JLabel alertIcon;
    private javax.swing.JButton confirmRenameButton;
    private dcobluej.draw.view.DrawMenuControl dcoMenuControl;
    private dcobluej.draw.view.DmeMenuControl dmeMenuControl;
    private javax.swing.JLabel hintIcon;
    private javax.swing.JLayeredPane jLayeredPane1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JPanel messagePanel;
    private javax.swing.JPanel renamePanel;
    private javax.swing.JTextField renameTextField;
    // End of variables declaration//GEN-END:variables

    // <editor-fold defaultstate="collapsed" desc="IView">
    @Override
    public void showMessage(String message, boolean isErrorMessage) {
        MessageTextPane.setText(message);
        MessageTextPane.setBackground(isErrorMessage ? LightRed : LightGreen);
        MessageTextPane.setForeground(isErrorMessage ? Red : Green);
        alertIcon.setVisible(isErrorMessage);
        hintIcon.setVisible(!isErrorMessage);
    }

    @Override
    public void cleanMessage() {
        MessageTextPane.setText("");
        MessageTextPane.setBackground(Gray);
        alertIcon.setVisible(false);
        hintIcon.setVisible(false);
    }

    @Override
    public void moveDraw(IDraw draw, Point newLocation) {
        draw.move((int) newLocation.getX().getCoordinate(), (int) newLocation.getY().getCoordinate());
        currentPanel.paint(currentPanel.getGraphics());
    }

    @Override
    public void showRenameField(boolean visible) {
        renamePanel.setVisible(visible);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Communicator Diagram View">   
    @Override
    public void manifestEntityDraw(IEntityDraw drawObject) {
        drawObject.draw(getDrawAreaGraphics());
    }

    @Override
    public List<IEntity> tryGetEntityAt(Point point) {
        List<IEntity> entities = new ArrayList<IEntity>();
        for (IEntityDraw draw : entityDraws) {
            if (draw.contains((int) point.getX().getCoordinate(), (int) point.getY().getCoordinate())) {
                entities.add(draw.getEntity());
            }
        }
        return entities;
    }

    @Override
    public List<IEntityDraw> tryGetDrawAt(Point point) {
        List<IEntityDraw> drawsAt = new ArrayList<IEntityDraw>();
        for (IEntityDraw draw : entityDraws) {
            draw.unselect();
            if (draw.contains((int) point.getX().getCoordinate(), (int) point.getY().getCoordinate())) {
                drawsAt.add(draw);
            }
        }
        return drawsAt;
    }

    @Override
    public void selectEntityFrom(Point point) {
        enableToolbar(false);
        renamePanel.setVisible(false);
        for (IEntityDraw draw : entityDraws) {
            draw.unselect();
            if (draw.contains((int) point.getX().getCoordinate(), (int) point.getY().getCoordinate())) {
                draw.select();
                drawSelected = draw;
                enableToolbar(!(draw instanceof LinkDraw));
            }
        }
    }

    @Override
    public void unselectAllEntities() {
        for (IDraw draw : entityDraws) {
            draw.unselect();
        }
        repaint();
    }

    @Override
    public void manifestStateMachine(StateMachine stateMachine) {
        String label = "<html><body topmargin=5 marginwidth=5 marginheight=15><font size=\"4\">" + stateMachine.getDescription() + "</font></body></html>";
        JPanel statePanel = new JPanel();
        statePanel.setBackground(Color.WHITE);
        stateMachine.setManifestArea(statePanel);
        DiagramTabbedPane.addTab(label, statePanel);
    }

    @Override
    public void saveDraw(IEntityDraw draw) {
        entityDraws.add(draw);
    }

    @Override
    public void setRenameDraw(IEntityDraw draw) {
        drawToRename = draw;
        renameTextField.setText(draw.getEntity().getDescription());
    }

    @Override
    public void enableMoving(boolean enable) {
        isMoving = enable;
    }

    @Override
    public void configureCommunicationContext() {
        enableDcoContext(true);
    }

    @Override
    public void updateTabWith(String newName, JPanel panel) {
        JPanel tab = findTab(panel);
        if (tab != null) {
            DiagramTabbedPane.remove(tab);
            DiagramTabbedPane.addTab("<html><body topmargin=5 marginwidth=5 marginheight=15><font size=\"4\">" + newName + "</font></body></html>", tab);
        }
    }

    @Override
    public void updateCommunicationCanvas() {
        drawsToUpdate.clear();
        for (IEntityDraw draws : entityDraws) {
            drawsToUpdate.add(draws);
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                repaint();
            }
        });
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="State Diagram View">   
    @Override
    public void manifestStateDraw(IMachineStateDraw draw) {
        draw.draw(currentPanel.getGraphics());
    }

    @Override
    public List<IMachineStateDraw> tryGetStateDrawAt(Point point) {
        List<IMachineStateDraw> draws = new ArrayList<IMachineStateDraw>();
        for (IMachineStateDraw draw : stateDraws) {
            if (draw.contains((int) point.getX().getCoordinate(), (int) point.getY().getCoordinate())) {
                draws.add(draw);
            }
        }
        return draws;
    }

    @Override
    public void selectStateFrom(Point point) {
        //TODO: Put this at presenter
        for (IMachineStateDraw draw : stateDraws) {
            draw.unselect();
            if (draw.contains((int) point.getX().getCoordinate(), (int) point.getY().getCoordinate())) {
                draw.select();
                drawSelected = draw;
                enableToolbar(true);
            }
        }
    }

    @Override
    public void setStateDrawList(List<IMachineStateDraw> draws) {
        this.stateDraws = draws;
    }

    @Override
    public void configureStateContext() {
        enableDcoContext(false);
    }

    @Override
    public void updateStateCanvas() {
        currentPanel.paint(currentPanel.getGraphics());
        drawsToUpdate.clear();
        for (IMachineStateDraw stateDraw : stateDraws) {
            drawsToUpdate.add(stateDraw);
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                repaint();
            }
        });
    }

    @Override
    public void saveDraw(IMachineStateDraw stateDraw) {
        stateDraws.add(stateDraw);
    }
    // </editor-fold>

    public void setCurrentEntity(IEntity currentEntity) {
        this.currentEntity = currentEntity;
    }

    public IEntity getCurrentEntity() {
        return currentEntity;
    }

    public Graphics getDrawAreaGraphics() {
        return currentPanel.getGraphics();
    }

    private void enableDcoContext(boolean activateDcoContext) {
        cleanMessage();
        unselectAllEntities();
        showRenameField(false);

        drawSelected = null;
        drawToRename = null;

        dmeMenuControl.enableButtons(!activateDcoContext);
        dcoMenuControl.enableButtons(activateDcoContext);

        RenameButton.removeActionListener(activateDcoContext ? stateRenameAction : communicationRenameAction);
        RenameButton.addActionListener(activateDcoContext ? communicationRenameAction : stateRenameAction);
        MoveButton.removeActionListener(activateDcoContext ? stateMoveAction : communicationMoveAction);
        MoveButton.addActionListener(activateDcoContext ? communicationMoveAction : stateMoveAction);
        confirmRenameButton.removeActionListener(activateDcoContext ? stateConfirmRename : communicationConfirmRename);
        confirmRenameButton.addActionListener(activateDcoContext ? communicationConfirmRename : stateConfirmRename);
    }

    private void enableToolbar(boolean enable) {
        MoveButton.setEnabled(enable);
        RenameButton.setEnabled(enable);
    }

    // <editor-fold defaultstate="collapsed" desc="Paint and Repaint actions">   
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        repaint();
    }

    @Override
    public void repaint() {
        currentPanel.removeAll();
        currentPanel.revalidate();
        if (drawsToUpdate != null) {
            for (IDraw drawObject : drawsToUpdate) {
                drawObject.draw(getDrawAreaGraphics());
            }
        }
    }
    // </editor-fold>

    private JPanel findTab(JPanel panel) {
        for (Component component : DiagramTabbedPane.getComponents()) {
            if (component.equals(panel)) {
                return (JPanel) component;
            }
        }
        return null;
    }

    private StateMachine findStateMachineOf(JPanel statePanel) {
        for (IEntityDraw draw : entityDraws) {
            if (draw.getEntity() instanceof ObjectEntity) {
                if (((ObjectEntity) draw.getEntity()).getStateMachine().getManifestArea() == statePanel) {
                    return ((ObjectEntity) draw.getEntity()).getStateMachine();
                }
            }
        }
        return null;
    }

    private void RenameStateButtonActionPerformed(ActionEvent evt) {
        stateMachinePresenter.StartRename((IMachineStateDraw) drawSelected);
    }

    private void RenameCommunicationButtonActionPerformed(ActionEvent evt) {
        if (!(drawSelected instanceof StateDraw) && !(drawSelected instanceof TransitionDraw)) {
            communicationDiagramPresenter.StartRenameEntity((IEntityDraw) drawSelected);
        }
    }

    private void MoveCommunicationButtonActionPerformed(ActionEvent evt) {
        if (!(drawSelected instanceof StateDraw) && !(drawSelected instanceof TransitionDraw)) {
            communicationDiagramPresenter.StartMoveEntity((IEntityDraw) drawSelected);
        }
    }

    private void MoveStateButtonActionPerformed(ActionEvent evt) {
        stateMachinePresenter.StartMoveEntity((IMachineStateDraw) drawSelected);
    }

    private void communicationConfirmRenameButtonActionPerformed(ActionEvent evt) {
        communicationDiagramPresenter.RenameEntity(drawToRename, renameTextField.getText());
    }

    private void stateconfirmRenameButtonActionPerformed(ActionEvent evt) {
        stateMachinePresenter.RenameEntity((IMachineStateDraw) drawToRename, renameTextField.getText());
    }

    @Override
    public void setRenameDraw(IMachineStateDraw draw) {
        drawToRename = draw;
        renameTextField.setText(draw.getDescription());
    }
}
